
//-----------------MATRICES---------------
float4x4 xWorld: World;				
float4x4 xView: View;
float4x4 xProjection: Projection;


//-----------------TEXTURES---------------

Texture xTexture;
sampler ColoredTextureSampler = sampler_state { texture = <xTexture> ;
    magfilter = ANISOTROPIC; minfilter = ANISOTROPIC; mipfilter=ANISOTROPIC; AddressU = mirror; AddressV = mirror;};
	
Texture xDOFMap;
sampler DOFSampler = sampler_state { texture = <xDOFMap> ;
    magfilter = LINEAR; minfilter = LINEAR; mipfilter=LINEAR; AddressU = mirror; AddressV = mirror;};

//--------------- CONSTANTS ---------------

float xDOFDistance;
float xDOFRange;
float xDOFFactor;

float xDX, xDY;

//------------------- STRUCTS -------------------   


struct BufferToVertex
{
	float3 Pos : POSITION;
	float4 Normal : NORMAL;
	float4 UV : TEXCOORD0;
};


struct VertexToPixel
{
	float4 Pos:POSITION;
	float4 Orig_Pos:TEXCOORD1;
	float4 UV:TEXCOORD0;
	float4 Normal: TEXCOORD2;
	float4 TexWeights: TEXCOORD3;
	float4 Pos3D:TEXCOORD4;
	float4 Pos2D:TEXCOORD5;
};


struct PixelToFrame
{
	float4 Color:COLOR;
	float Depth:DEPTH;
};


struct BufferToVertexT2S
{
	float3 Pos : POSITION;
	float4 UV : TEXCOORD0;
};



struct VertexToPixelT2S
{
	float4 Pos:POSITION;
	float4 UV:TEXCOORD0;
	float4 Pos2D:TEXCOORD1;
};


struct PixelToFrameT2S
{
	float4 Color:COLOR;
};


//---------------------- HELPERS ---------------------

float4 BluredSample(float2 UV, out float4 unblured)
{
	float4 S1=tex2D(ColoredTextureSampler, UV);
	float4 S2=tex2D(ColoredTextureSampler, UV+float2(xDX,xDY));
	float4 S3=tex2D(ColoredTextureSampler, UV+float2(0,xDY));
	float4 S4=tex2D(ColoredTextureSampler, UV+float2(0,-xDY));
	float4 S5=tex2D(ColoredTextureSampler, UV+float2(xDX,0));
	float4 S6=tex2D(ColoredTextureSampler, UV+float2(-xDX,0));
	float4 S7=tex2D(ColoredTextureSampler, UV+float2(-xDX,-xDY));
	float4 S8=tex2D(ColoredTextureSampler, UV+float2(-xDX,xDY));
	float4 S9=tex2D(ColoredTextureSampler, UV+float2(xDX,-xDY));
	unblured=S1;
	float4 r=S1+S2+S3+S4+S5+S6+S7+S8+S9;
	r/=9.0;
	return r;
}

//---------------------- SHADERS ------------------------

//---------- TEXTURE TO SCREEN ---------------

VertexToPixelT2S T2SVS(BufferToVertexT2S IN)
{
	VertexToPixelT2S OUT = (VertexToPixelT2S)0;
	OUT.Pos=float4(IN.Pos.xyz,1.0);
	OUT.Pos2D=float4(IN.Pos.xyz,1.0);
	OUT.UV=float4(IN.UV.xy,1.0,1.0);
	return OUT;
}

PixelToFrameT2S T2SPS(VertexToPixelT2S IN) 
{
	PixelToFrameT2S OUT = (PixelToFrameT2S)0;

	float4 res=tex2D(ColoredTextureSampler, IN.UV);
	OUT.Color=res;
	return OUT;
}

PixelToFrameT2S T2SDOFPS(VertexToPixelT2S IN) 
{
	PixelToFrameT2S OUT = (PixelToFrameT2S)0;
	float f=tex2D(DOFSampler, IN.UV).r;
	float4 N,B;
	B=BluredSample(IN.UV,N);
	float4 c=f*N+(1-f)*B;
	OUT.Color=c;
	return OUT;
}

PixelToFrameT2S T2SFogPS(VertexToPixelT2S IN) 
{
	PixelToFrameT2S OUT = (PixelToFrameT2S)0;
	float f=tex2D(DOFSampler, IN.UV).r;
	float4 c=tex2D(ColoredTextureSampler, IN.UV);
	float4 o=saturate(c+f*float4(1,1,1,1));
	OUT.Color=o;
	return OUT;
}

// ---- DepthOfFieldMap ------
VertexToPixel dofVS(BufferToVertex IN)
{
	  VertexToPixel OUT = (VertexToPixel)0;
	  float4x4 WorldViewProj;
	  WorldViewProj=mul(xWorld,xView);
	  WorldViewProj=mul(WorldViewProj,xProjection);
	  OUT.Pos=mul(float4(IN.Pos.xyz,1.0), WorldViewProj);
	  OUT.Pos2D=OUT.Pos;
	  OUT.Pos3D=mul(float4(IN.Pos.xyz,1.0),xWorld);
	  OUT.Orig_Pos=float4(IN.Pos.xyz,1.0);
	  OUT.UV=float4(IN.UV.xy,1.0,1.0);
	  OUT.Normal=IN.Normal;
	  return OUT;
}

PixelToFrame dofPS(VertexToPixel IN) 
{
	PixelToFrame OUT = (PixelToFrame)0;
	OUT.Depth=IN.Pos2D.z/IN.Pos2D.w;
	float f=(IN.Pos2D.z-xDOFDistance);
	if (f<0) f=0;
	f*=xDOFFactor;
	//f=1-f;
	OUT.Color=float4(f,f,f,0);
	return OUT;
}


// ------------ TECHNIQUES --------------

technique T2S{
	pass p0 {
		
		VertexShader = compile vs_3_0 T2SVS();
		PixelShader = compile ps_3_0 T2SPS();
	}
}

technique T2SDOF{
	pass p0 {
		
		VertexShader = compile vs_3_0 T2SVS();
		PixelShader = compile ps_3_0 T2SDOFPS();
	}
}


technique T2SFog{
	pass p0 {
		
		VertexShader = compile vs_3_0 T2SVS();
		PixelShader = compile ps_3_0 T2SFogPS();
	}
}


technique dof{
	pass p0 {
		
		VertexShader = compile vs_3_0 dofVS();
		PixelShader = compile ps_3_0 dofPS();
	}
}
